iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
自我挑戰組

一鍵完成六套開源防禦系統整合系列 第 25 篇

EveBox:翻 Suricata 每一行紀錄的窗口

  • 分享至 

  • xImage
  •  

防禦節點(主機 B)上除了 WAF,還裝了幾個別人寫的repo。「搭配元件篇」這一系列每篇只談一個,不深入它的設定細節,只回答三件事:它是什麼、它在主機 A 與主機 B 之間佔哪一段、少了它整體會缺什麼。本篇是第六篇 EveBox。主機與位址沿用防禦節點那一套:主機 A(192.168.0.111)是 BeakPlatform,主機 B(192.168.0.112)是防禦節點。

先講結論。 EveBox 是 Suricata 輸出檔的瀏覽器。Suricata 把看到的每一條連線、每一次 HTTP、每一個 DNS 查詢和每一筆告警都寫進同一個檔案 eve.json,EveBox 跟著讀這個檔案,存進自己的小資料庫,讓人在瀏覽器裡翻。它不偵測、不判斷、不封鎖,主機 A 也不經過它;停掉它,事件照常送往主機 A,WAF 照常擋。它補上的是整套架構裡其他地方都沒有的東西:告警以外的那些紀錄,也就是「那個位址當時還連了哪裡、查了什麼網域」,而且留 7 天,比檔案本身的 48 小時長。

另外有一段過程值得先知道:2026 年 10 月 9 日之前的安裝包內建的是 0.18.2,一遇到沒有來源位址的告警就畫不出清單,而這種告警在這台節點上動輒一小時幾千筆、永遠排在最前面,所以出廠的收件匣一直停在 Loading。現在的安裝包已換成 0.28.0。第四節講這件事的來龍去脈:清單為什麼壞、換版對已裝過的人有什麼影響,以及那幾千筆告警到底從哪裡來。

一、它是什麼

EveBox 是 Jason Ish 寫的開源工具,授權 MIT。作者同時是 Suricata 的核心開發者之一,這個工具就是專門為 Suricata 的 EVE 格式(eve.json,一行一筆 JSON)做的:讀檔、存進資料庫、提供一個網頁介面翻紀錄。它可以接 Elasticsearch,也可以自己用 SQLite 存;本安裝包用的是後者,整個 EveBox 只有一個容器、不需要任何別的服務。容器映像是 jasonish/evebox:0.28.0(2026 年 8 月發布),官方未修改的版本;2026 年 10 月 9 日之前的安裝包是 0.18.2,差別見第四節。

它在本安裝包裡的樣子:

項目 內容
是否安裝 預設會裝。安裝時加 --no-ui 就不裝,Grafana 與 Portainer 也一起不裝
網址 http://192.168.0.112:5636/,HTTP
誰能連 由主機 B 的防火牆限制來源:安裝時 --admin-ips 列出的位址與主機 A。其他來源連線逾時
帳號 沒有。安裝包以 --no-auth 啟動,開了就能用,防火牆的來源限制是唯一的門
讀什麼 Suricata 的 eve.json。那個檔案放在 Suricata 的資料卷裡,EveBox 以唯讀方式掛進來
存在哪裡 它自己的 SQLite 資料庫,放在名為 evebox-data 的資料卷。事件在這裡保留 7 天,到期自動刪
資源 實測一台節點閒置時約佔 25 MB 記憶體;資料庫跑了 16 天是 385 MB

二、它接在哪裡

https://ithelp.ithome.com.tw/upload/images/20261009/201842610Jbuffg3Zx.png
(圖01:EveBox 的位置。黑色實線是人與 EveBox、EveBox 與檔案之間的讀取方向,藍色虛線是事件本來的路徑:Suricata 寫檔,Vector 讀檔送往 ClickHouse 與主機 A。灰色是它自己的資料庫。)

圖上有三件事要看。

  • 它和 Vector 讀的是同一個檔案,但拿的東西不同。 Vector 只取 alert,而且要有來源與目的位址,轉成共同格式後送 ClickHouse 與主機 A。EveBox 整個檔案都讀,連線、HTTP、DNS、TLS 全部進它的資料庫。所以主機 A 與 ClickHouse 裡的 Suricata 事件,是 EveBox 裡的一小部分。
  • 它在事件路徑的旁邊,不在路徑上。 Suricata 寫檔、Vector 讀檔送出,這條線上沒有 EveBox。它跟著檔案的尾端讀,讀到的東西只進自己的資料庫。
  • 它不往外連。 實測查看容器的網路連線,除了瀏覽器連進來的,沒有任何往外的連線。這點和 Grafana、Portainer 不同,那兩個都會定期連回原廠。

三、打開之後看到什麼

在 --admin-ips 列出的電腦上開 http://192.168.0.112:5636/,不用登入,直接進到收件匣。介面是英文的,上方選單有七項:

選單 內容 在本安裝包的節點上
Inbox 還沒歸檔的告警,同一條規則的合併成一列,顯示次數、最近一次的時間、來源與目的。每列可以 Archive(歸檔)或 Escalate(標記) 出廠狀態畫不出來,見第四節
Escalated 被標記過的告警 同上
Alerts 所有告警,含已歸檔的 同上
Stats Suricata 自己的計數器:封包數、丟包數、每種協定的筆數 空白。安裝包的 Suricata 沒有開 stats 這種輸出,EveBox 沒有東西可畫
Events 全部紀錄,不限告警。可依類型篩選:Alert、DNS、Flow、HTTP、TLS、Anomaly 等 正常。這是本篇最有用的一頁
Reports 過去一段時間內最常命中的規則、最常出現的來源與目的位址 正常
Help 說明 點了回到收件匣

Events 這一頁是其他地方看不到的。它一列一筆,最新的在上面,每一列是時間、類型、來源與目的、一句描述。在一台對外服務的節點上,隨手翻到的是這樣:

2026-10-09 19:49:08  FLOW  S: 192.168.0.50 → D: 192.168.0.112   TCP 192.168.0.50:[49258] => 192.168.0.112:[22] Age=1 Packets=43 Bytes=11276 ssh
2026-10-09 19:49:05  HTTP  S: 192.168.0.50 → D: 192.168.0.112   GET 192.168.0.112 /assets/index-D5FC6rcL.js.map
2026-10-09 19:49:03  HTTP  S: 192.168.0.50 → D: 192.168.0.112   GET 192.168.0.112 /api/1/alerts?time_range=86400s&tags=-evebox.archived
2026-10-09 19:48:56  FLOW  S: 192.168.0.50 → D: 239.255.255.250  UDP 192.168.0.50:[64916] => 239.255.255.250:[3702] Age=7 Packets=7 Bytes=4662

第一列是管理者從工作機來的 SSH 連線,第二、三列是同一台工作機的瀏覽器正在開 EveBox 自己,第四列是它的服務探索廣播。這些都不是告警,不會出現在 ClickHouse,更不會到主機 A。但當主機 A 上有一張案件寫著「某位址對 WAF 送了攻擊請求」,想知道那個位址在前後幾分鐘內還對主機 B 做了什麼,只有這裡翻得到。在 Events 頁的篩選欄填 src_ip:那個位址,就是那個位址在主機 B 網卡上留下的全部痕跡。

它的資料庫在這台節點上存了什麼,用數字看一次。跑了 16 天、保留 7 天,資料庫裡有 199,579 筆:

flow     114,418   每條連線結束時一筆
http      64,687   每個 HTTP 交易一筆
alert     12,661   告警
dns        6,467
tls        1,485
anomaly       79

告警佔 6%。其中絕大多數又是同兩條:

6,221  SURICATA IPv4 truncated packet
6,221  SURICATA AF-PACKET truncated packet
  158  SURICATA HTTP too many warnings
   20  SURICATA STREAM Packet with invalid timestamp
   19  ET INFO GNU/Linux APT User-Agent Outbound likely related to package management
    6  ET FILE_SHARING File Hosting Service Domain Domain in DNS Lookup (files .pythonhosted .org)
    3  ET WEB_SERVER ColdFusion administrator access

前兩條是 Suricata 自己的解碼告警,意思是收到的封包比標頭宣告的長度短。官方文件說主因是網卡的卸載功能把超過 MTU 的大封包交給 Suricata,安裝包也早就在主機 B 關掉了 gro、lro、tso、gso 四項,但這台節點上它們還是一直出現,而且集中在少數幾個小時:某一個小時 4,668 筆,其他小時 0 筆。根因在第四節一起講。它們不是攻擊,沒有來源也沒有目的位址,Vector 一律不送,所以 ClickHouse 與主機 A 都看不到它們。EveBox 看得到,而且就是它們讓舊版的收件匣壞掉。

四、收件匣曾經畫不出來:舊版的問題、換版、告警的根因

如果您沒安裝過10/9之前的版本可略過第四章
先講舊版。2026 年 10 月 9 日之前的安裝包內建 0.18.2,打開 Inbox,畫面停在 Loading,上方寫著 Alerts 1-0 of 5:伺服器回了 5 組告警,畫面上一列都沒有。Alerts 頁也一樣。按 F12 看主控台,有一個錯誤,位置在前端程式的 AddressCell:

export function AddressCell(props: { source: EventSource }) {
  return (
    <>
      S: {formatAddress(props.source.src_ip)}
      <br />
      D: {formatAddress(props.source.dest_ip)}
    </>
  );
}

export function formatAddress(addr: string) {
  return addr.replace(/(0000\:)+/, ":");
}

每一列都要畫來源與目的位址,畫的方法是對位址字串做一次取代。解碼告警沒有 src_ip,對不存在的東西做取代,整頁的渲染就中斷。只要清單裡有一筆這種告警,整張清單就畫不出來;而這兩條解碼告警在這台節點上動輒一小時幾千筆,永遠是過去 24 小時裡最新的告警,所以收件匣永遠停在 Loading。

實測可以證明是這個原因:在網址列指定只看某一條有位址的規則,http://192.168.0.112:5636/#/alerts?q=alert.signature_id:2210044,清單正常出現,來源與目的都畫得出來;改成指定解碼告警那條,alert.signature_id:2200003,又是 Loading。Reports 頁不畫位址欄,所以它正常,而且第一列就是這兩條解碼告警各 2,615 筆。

這是舊版本的問題。0.18.2 發布於 2024 年,EveBox 在本文寫作時的最新版是 0.28.0(2026 年 8 月)。實測把新版跑起來讀同一份 eve.json,收件匣正常,解碼告警那兩列的來源與目的欄是空的,其他列照畫:

#     Timestamp            Src / Dst                           Signature
1101  2026-10-09 19:59:48                                      SURICATA IPv4 truncated packet
1101  2026-10-09 19:59:48                                      SURICATA AF-PACKET truncated packet
   1  2026-10-09 19:56:02  S: 3.169.55.12  D: 192.168.0.112    SURICATA STREAM FIN out of window
   1  2026-10-09 19:56:02  S: 192.168.0.112  D: 3.169.55.12    SURICATA STREAM FIN invalid ack

安裝包從 2026 年 10 月 9 日起改用 0.28.0。新裝的讀者直接拿到新版,沒有這個問題;已經裝過、用 install.sh --update 升上來的讀者,有兩件事會發生:

  • 既有資料庫自動升級。 新版第一次啟動時會印 Found legacy schema version, migrating to SQLx,把舊版的 SQLite 資料庫換成新版的格式,資料不會少(實測 199,876 筆、7 天份全部都在)。但它不會順手重建索引,之後每次啟動都留一行 Event table indexes out of date, please consider updating the indexes,查詢會比較慢。install.sh 看到這一行會自動停掉 EveBox、用它自己的 evebox sqlite reindex --remove --force 重建,再啟動;386 MB 的資料庫約一分鐘。
  • 網頁 API 路徑改了。 舊版的 /api/1/version 在新版回 404,新版是 /api/version。第七節的指令已經是新版的。

最後是那幾千筆解碼告警到底從哪裡來。主機 B 是虛擬機,網卡是 virtio。Linux 把「宿主機幫忙把連續的 TCP 封包合併成一個大封包再交給虛擬機」這件事叫 rx-gro-hw(硬體 GRO),它和 gro、lro、tso、gso 四項是分開的開關,關掉那四項不會關到它。宿主機合併好的大封包就這樣進來,Suricata 的擷取長度是照 MTU 1500 算的,超過的部分被截掉,記成 truncated。實測很直接:往主機 B 傳一個 200 MB 的檔案,四項關、rx-gro-hw 開,傳完多了 12,834 筆 truncated 告警;把 rx-gro-hw 也關掉再傳一次,0 筆。這也解釋了它們為什麼集中在少數幾個小時:那是有人往主機 B 傳大檔案的時候,例如 docker pull 映像或備份。

# 主機 B
sudo ethtool -k ens18 | grep -E "generic-receive|rx-gro-hw"
generic-receive-offload: off
rx-gro-hw: on                      ← 四項都關了,它還開著

sudo ethtool -K ens18 rx-gro-hw off

安裝包的 integrated-waf-offload.service 從 2026 年 10 月 9 日起多關這一項,開機後也維持。實體網卡多半沒有這個開關,關不掉不算錯,所以它寫在獨立的一行、失敗不影響服務。這兩條解碼告警本來就不是攻擊,Suricata 的規則沒有停用,它們只是不再有理由出現。

五、它存了什麼、留多久

Suricata 的輸出檔由主機 B 每小時輪替一次、保留 48 小時(搭配元件篇 1 第四節)。EveBox 把讀到的每一行存進自己的資料庫,預設保留 7 天。所以同一筆紀錄有三個去處、三種壽命:

去處 收什麼 留多久
eve.json 檔案 全部 48 小時
EveBox 的資料庫 全部 7 天。每分鐘清一次到期的
ClickHouse 與主機 A 只有帶位址的告警 ClickHouse 90 天;主機 A 的案件不過期

這代表「那個位址還連了哪裡」這種問題,第 3 天到第 7 天只有 EveBox 答得出來。第 8 天起誰也答不出來。想留更久,EveBox 有保留天數的設定,但安裝包沒有開放這個參數,要自己改 compose 檔。

讀檔的進度它記在一個書籤檔裡,所以停掉再啟動不會漏。實測停止容器 29 秒:這段期間 eve.json 照常被 Suricata 寫入,對 WAF 送的攻擊請求照常回 403;重新啟動後紀錄裡寫 Valid bookmark found, jumping to record: 981,從停下來的地方接著讀,停機期間寫進檔案的紀錄全部補進資料庫。每小時的輪替它也認得,紀錄裡會出現 File may have been rotated, will reopen。唯一會漏的情況是停機超過一個輪替週期:書籤指向的檔案已經被搬走,接不回去。

資料庫跟著資料卷走,規則和 Grafana 那一篇相同:重啟、--update、不加 --purge 的 --uninstall 都保留;--uninstall --purge 或整台重灌就沒了。沒了也不要緊,它裡面沒有任何別處沒有的判斷結果,只是過去 7 天的原始紀錄。

六、它不做的事

限制 說明
不偵測、不判斷 它顯示的告警是 Suricata 判的。歸檔與標記只是改它自己資料庫裡的兩個旗標,Suricata、Vector、主機 A 都不知道
不通知 沒有警示、沒有寄信。本系列裡「有事要通知人」走主機 A 的案件流程
看不到主機 A 案件、簽核、封鎖決策都不在這裡。反過來主機 A 也不會連它
只看 Suricata WAF 的 audit.log、CrowdSec 的紀錄都不在裡面。WAF 擋下的攻擊請求,在這裡只看得到 Suricata 那一側的紀錄,也就是一筆 HTTP 與一筆 FLOW,上面不會寫「被擋了」
沒有帳號 開了就能用,能歸檔、能標記。防火牆的來源限制是唯一的門,所以 --admin-ips 列出的每一台電腦都等於有它的全部權限
連線不加密 5636 埠是 HTTP。和 Grafana 一樣假設管理者的電腦在可信任的網段
沒有地理位置 它支援查位址所屬的國家,但需要另外下載資料庫。安裝包沒有放,啟動紀錄裡有一行 Failed to open GeoIP database,功能關閉
Stats 頁空白 需要 Suricata 開 stats 輸出,安裝包沒開
舊版(0.18.2)的清單畫不出來 第四節。安裝包已換 0.28.0;用 --update 升上來的資料庫會自動升級並重建索引
不會自己更新 版本跟著安裝包走

所以它在整體裡的位置是這樣的:事件怎麼來、誰判斷、誰封鎖,都和它無關;它只負責把 Suricata 寫下的每一行,變成在瀏覽器裡翻得動的東西,而且比檔案多留 5 天。少了它,告警一筆都不會少,少的是「告警前後發生了什麼」這個問題在第 3 天之後的答案。

七、怎麼確認它在做事

先看它活著沒有。這個端點不必登入:

# 主機 B
curl -s http://127.0.0.1:5636/api/version
{"revision":"a204fa83","version":"0.28.0"}

再看它有沒有在讀檔、有沒有在清。舊版每分鐘印一行「過去 60 秒刪掉幾筆」,新版不印了,改用它自己的 info 指令看資料庫的頭尾(時間是 UTC):

# 主機 B
cd /opt/integrated-waf
sudo docker compose run --rm --no-deps --entrypoint /usr/bin/evebox evebox \
  sqlite info -D /data /data/events.sqlite
Filename: /data/events.sqlite
Number of events (estimate): 212633
Schema version: 5
Oldest event: Some(2026-10-02T13:38:01.292295Z)
Latest event: Some(2026-10-09T13:38:53.832936Z)

「最新一筆」應該在一分鐘內,那是讀得進;「最舊一筆」應該在 7 天前左右,那是清得掉。剛裝好的節點最舊一筆就是裝機那天,要到第 8 天才開始往前推。不想下指令就看 Events 頁:最上面那一列的時間應該在一分鐘內。

最後看有沒有人在用它。管理面的防火牆規則有計數器,每一個進得來的封包都會加上去:

# 主機 B
sudo nft list chain inet secstack mgmt_guard_forward
    tcp dport { 3000, 5636, 8686, 9443 } ip saddr { 192.168.0.111, 192.168.0.50 } counter packets 1327 bytes 118854 accept
    tcp dport { 3000, 5636, 8686, 9443 } counter packets 0 bytes 0 drop

第一行是放行的,第二行是被擋的。實測開 EveBox 翻了幾頁,第一行從 0 變成 1327;第二行一直是 0,代表沒有名單以外的來源試過。這個計數器四個管理埠共用,分不出是誰在用哪一個,但「第二行開始變大」這件事值得知道:那是有人從不在名單上的位址連過來。

上一篇是搭配元件篇 5 Grafana,下一篇是搭配元件篇 7 Portainer。


上一篇
Grafana:線接好了,畫面要自己畫
下一篇
Portainer:容器的管理畫面
系列文
一鍵完成六套開源防禦系統整合 共 29 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言